<?php


namespace app\common\business;


use app\common\lib\Redis;
use app\common\lib\ZhyxBeanstalkd;
use app\common\lib\ZhyxMongo;
use app\common\model\BaseModel;
use app\common\model\DiseasePatientTaskDetail;
use app\common\model\Follow;
use app\common\model\PatientInfo;
use app\common\model\FollowHistory;
use app\common\utils\Ip;
use app\common\utils\Str;
use catchAdmin\registration\service\TaskService;
use catcher\base\CatchRequest;
use catcher\exceptions\CatchException;
use catcher\exceptions\FailedException;
use catcher\Utils;
use MongoDB\BSON\ObjectId;
use PhpParser\Node\Expr\Cast\Object_;
use think\Db;
use think\Exception;
use think\facade\Log;

class Answer
{
    protected $model = null;

    public function __construct()
    {
        $this->model = new \app\common\model\Answer();
    }


    public function getAnswerInfo(string $projectId, string $hisId)
    {
        /*$answerInfo = $this->model->where([
            ["projectId", "=", $projectId],
            ["patient_id", "=", $hisId],
            ["answer", "=", []]
        ])->order("startTime", "desc")->find();
*/
        //, "answer" => []
        $answerInfo = ZhyxMongo::getInstance()->setCollection('answer')->findOne(["projectId" => $projectId, "deleted_at" => 0, "patient_id" => $hisId, "answer" => []], ['sort' => ['created_at' => -1]]);
        if (empty($answerInfo)) {
            throw new FailedException("未分配随访不能做答");
        }
        return $answerInfo;
    }

    public function createAnswer(array &$data)
    {
        
        $connection = ZhyxMongo::getInstance()->connection;
        $session = $connection->startSession();
        try {
            $session->startTransaction(['session' => $session]);
            $questionInfo = (new Project())->getProjectInfo($data["projectId"]);
            if (empty($questionInfo)) {
                throw new FailedException("问卷不存在");
            }
            if ($questionInfo["status"] !== 1) {
                throw new FailedException("问卷未开启");
            }

            if (isset($questionInfo["isEnd"]) && $questionInfo["isEnd"] === 1) {
                throw new FailedException("本次随访任务已过期，不能进行作答");
            }

            if (isset($data["answer_id"]) && !empty($data["answer_id"])) {
                $answerInfo = $this->getAnswerById($data["answer_id"]);
                if ($answerInfo["status"] === 2) {
                    throw new FailedException("请不要重复答题");
                }
            } else {
              
                # 判断问卷类型是否是公开二维码类型，如果是二维码问卷，先创建一个问卷
                if (isset($questionInfo["dept_list"]) && !empty($questionInfo["dept_list"])) {
                    $patientInfo = (new PatientInfo())->getPatientInfo($data["his_id"]);
                    // 执行问卷的创建
                    $result = (new Answer())->initQuestion([
                        'projectId' => $data['projectId'],
                        'putChanel' => 'ALL',
                        'deleted_at' => 0,
                        'patientList' => [[
                            'sex' => $patientInfo["sex"],
                            'inage' => $patientInfo["inage"],
                            'name' => $patientInfo["name"],
                            'mobile' => $patientInfo["presentTelphone"],
                            'patient_id' => $patientInfo["patientId"],
                            'birthdate' => $patientInfo["birthdate"] ?? "",
                            'task_id' => $data['task_id'] ?? "",
                            'follow_id' => $data['follow_id'] ?? "",
                        ]]
                    ]);
                    $answerId = $result["answer_ids"];

                    if (!empty($answerId)) {
                        $answerInfo = $this->getAnswerById((string)$answerId);
                    } else {
                        throw new FailedException("初始化问卷失败");
                    }
                } else {
                    $answerInfo = $this->getAnswerInfo($data["projectId"], $data["his_id"]);
                }
            }

            $data["task_id"] = $answerInfo["task_id"] ?? "";

            if (!isset($answerInfo["startTime"]) || $answerInfo["startTime"] !== false) {
                $answerInfo["startTime"] = $startTime = $data["pc_answer_start_time"] ?? time();
                $data["startTime"] = $startTime;
            }

            $ipInfo = Ip::getIpText(Ip::getRealIp());
            $data["status"] = 2;
            //标记答题完成时间
            $data["endTime"] = time();
            $data["timeCost"] = date("H小时i分s秒", mktime(0, 0, ($data["endTime"] - $answerInfo["startTime"])));

            if ($questionInfo["survey_type"] === 2) {
                $totalScore = 0;
                foreach ($data["answer"] as $k => $v) {

                    foreach ($v["solution"] as $ak => $av) {
                        $totalScore += (int)$av["value"];
                    }
                }
            }
            //生成答题编号
            $createData = array_merge($ipInfo, $data);
            $result = ZhyxMongo::getInstance()->setCollection('answer')->updateOne(["_id" => $answerInfo["_id"]], ['$set' => $createData], ['session' => $session]);

            if ($result) {
                //获取完整的问题列表
                $cursor = ZhyxMongo::getInstance()->setCollection('question_detail')->find(['projectId' => $questionInfo["id"]]);
                $questionList = [];
                $answerList = [];
                foreach ($cursor as $k => $v) {
                    $questionList[$v["question_id"]] = [
                        'id' => (string)$v["_id"],
                        'type' => $v["type"]
                    ];
                }
                //拆分题目
                foreach ($data["answer"] as $k => $v) {
                    foreach ($v["solution"] as $kk => $vv) {
                        $answerList[] = [
                            'questionId' => $questionList[$v["id"]]["id"],
                            'questionType' => $questionList[$v["id"]]["type"],
                            'value' => $vv['value'],
                            'label' => $vv['label'],
                            'textcontent' => $vv['textcontent']??"",
                            'task_id' => $answerInfo["task_id"] ?? ""
                        ];
                    }
                }


                //执行入库操作
                ZhyxMongo::getInstance()->setCollection('answer_detail')->insertMany($answerList, ['session' => $session]);
                ZhyxMongo::getInstance()->setCollection('project')->updateOne(['_id' => new ObjectId($questionInfo["id"])], ['$inc' => ['answer_number' => 1]], ['session' => $session]);
        

                $answerId = (string)$answerInfo["_id"];
                $key = "projectAndAnswer:".$data['projectId'].":".$data["his_id"];
                Redis::getInstance()->redis->set($key,json_encode(['projectId' => $data["projectId"], 'answer_id' => $answerId]));
                //判断问卷id是否绑定过节点问卷
                if (isset($answerInfo["patientDeptId"]) && !empty($answerInfo["patientDeptId"])) {
                    $nodeInfo = (new \app\common\model\Node())->where([["project_id", "=", $data["projectId"]]])->where(function ($query) use ($answerInfo) {
                        $query->whereOr([["apply_dept.dept_id", "=", (int)$answerInfo["patientDeptId"]], ["is_whole_hospital", "=", 1]]);
                    })->order("is_whole_hospital", "asc")->limit(1)->find();
                    if (!empty($nodeInfo)) {
                        # 执行回复量+1
                        ZhyxMongo::getInstance()->setCollection('node')->updateOne(["_id" => new ObjectId($nodeInfo["id"])], ['$inc' => ['answer_count' => 1]]);
                    }
                }
            
                if (isset($data["follow_id"]) && $data["follow_id"] != 0 && ($data["putChannel"] =="pc" || $data["putChannel"]=="qrcode") ) {
                   
                    (new Follow())->saveData($data["follow_id"],["status"=>2,"followStatus"=>1,'answer_id'=>$data['answer_id']]);
                    (new FollowHistory())->where('follow_id', new ObjectId($data["follow_id"]))->update(['status'=>2]);
                    Redis::getInstance()->redis->del($key);
                    
                }
                $session->commitTransaction();
            }

        } catch (\Exception $exception) {

            if ($session->getTransactionState() !== "none") {
                $session->abortTransaction();
            }
            throw  new FailedException($exception->getMessage());
        }
        return ["id" => (string)$answerInfo["_id"], "status" => 2];

    }

//    public function createAnswer(array &$data)
//    {
//
//        $connection = ZhyxMongo::getInstance()->connection;
//        $session = $connection->startSession();
//        try {
//            $session->startTransaction(['session' => $session]);
//            $questionInfo = (new Project())->getProjectInfo($data["projectId"]);
//            if (empty($questionInfo)) {
//                throw new FailedException("问卷不存在");
//            }
//            if ($questionInfo["status"] !== 1) {
//                throw new FailedException("问卷未开启");
//            }
//
//            if (isset($questionInfo["isEnd"]) && $questionInfo["isEnd"] === 1) {
//                throw new FailedException("本次随访任务已过期，不能进行作答");
//            }
//
//            if (isset($data["answer_id"]) && !empty($data["answer_id"])) {
//                $answerInfo = $this->getAnswerById($data["answer_id"]);
//                if ($answerInfo["status"] === 2) {
//                    throw new FailedException("请不要重复答题");
//                }
//            } else {
//
//                # 判断问卷类型是否是公开二维码类型，如果是二维码问卷，先创建一个问卷
//                if (isset($questionInfo["is_code"]) && $questionInfo["is_code"] === 1) {
//                    // 执行问卷的创建
//                    $result = (new Answer())->initQuestion([
//                        'projectId' => $data['projectId'],
//                        'putChanel' => 'ALL',
//                        'deleted_at' => 0,
//                        'patientList' => [[
//                            'sex' => '3',
//                            'inage' => 0,
//                            'name' => '患者',
//                            'mobile' => '-',
//                            'patient_id' => '0',
//                            'follow_id' => 0
//                        ]]
//                    ]);
//                    $answerId = $result["answer_ids"];
//                    if (!empty($answerId)) {
//                        $answerInfo = $this->getAnswerById((string)$answerId);
//                    } else {
//                        throw new FailedException("初始化问卷失败");
//                    }
//                } else {
//                    $answerInfo = $this->getAnswerInfo($data["projectId"], $data["his_id"]);
//                }
//            }
//            $data["task_id"] = $answerInfo["task_id"] ?? "";
//
//            if (!isset($answerInfo["startTime"]) || $answerInfo["startTime"] !== false) {
//                $answerInfo["startTime"] = $startTime = $data["pc_answer_start_time"] ?? time();
//                $data["startTime"] = $startTime;
//            }
//
//            $ipInfo = Ip::getIpText(Ip::getRealIp());
//            $data["status"] = 2;
//            //标记答题完成时间
//            $data["endTime"] = time();
//            $data["timeCost"] = date("H小时i分s秒", mktime(0, 0, ($data["endTime"] - $answerInfo["startTime"])));
//
//            if ($questionInfo["survey_type"] === 2) {
//                $totalScore = 0;
//                foreach ($data["answer"] as $k => $v) {
//
//                    foreach ($v["solution"] as $ak => $av) {
//                        $totalScore += (int)$av["value"];
//                    }
//                }
//            }
//            //生成答题编号
//            $createData = array_merge($ipInfo, $data);
//            $result = ZhyxMongo::getInstance()->setCollection('answer')->updateOne(["_id" => $answerInfo["_id"]], ['$set' => $createData], ['session' => $session]);
//            if ($result) {
//                //获取完整的问题列表
//                $cursor = ZhyxMongo::getInstance()->setCollection('question_detail')->find(['projectId' => $questionInfo["id"]]);
//                $questionList = [];
//                $answerList = [];
//                foreach ($cursor as $k => $v) {
//                    $questionList[$v["question_id"]] = [
//                        'id' => (string)$v["_id"],
//                        'type' => $v["type"]
//                    ];
//                }
//                //拆分题目
//                foreach ($data["answer"] as $k => $v) {
//                    foreach ($v["solution"] as $kk => $vv) {
//                        $answerList[] = [
//                            'questionId' => $questionList[$v["id"]]["id"],
//                            'questionType' => $questionList[$v["id"]]["type"],
//                            'value' => $vv['value'],
//                            'label' => $vv['label'],
//                            'task_id' => $answerInfo["task_id"] ?? ""
//                        ];
//                    }
//                }
//                //执行入库操作
//                ZhyxMongo::getInstance()->setCollection('answer_detail')->insertMany($answerList, ['session' => $session]);
//                ZhyxMongo::getInstance()->setCollection('project')->updateOne(['_id' => new ObjectId($questionInfo["id"])], ['$inc' => ['answer_number' => 1]], ['session' => $session]);
//                if (isset($answerInfo["follow_id"]) && $answerInfo["follow_id"] !== 0) {
//
//                    //回写follow表状态
//                    (new Follow())->saveData($answerInfo["follow_id"],
//                        [
//                            "status" => 2,
//                            "followStatus" => 1,
//                            "result" => 29,
//                            "resultName" => '生存',
//                            "is_effective" => 1,
//                            "resultCategory" => 0
//                        ]
//                    );
//
//                    //更新患者最新随访记录
//                    $patientData['follow_node'] = [
//                        'follow_time' => date("Y-m-d"),
//                        'mode' => '问卷',
//                        'source' => '随访计划',
//                        'result' => 29,
//                        'resultName' => '生存'
//                    ];
//
//                    //更新任务状态为随访完成
//                    $patientData['establish_followtask_node.followStatus'] = 1;
//
//                    //查询当前患者pid
//                    $followInfo = (new Follow())->where('id', $answerInfo["follow_id"])->field('pid')->find();
//                    (new PatientInfo())->saveData($followInfo['pid'], $patientData);
//
//                    //追加随访结果到患者信息
//                    $pResult = [
//                        'history_id' => (string)$answerInfo["history_id"],
//                        'result' => 29,
//                        'resultCategory' => 0,
//                        'resultName' => '生存',
//                        'resultIsEffective' => 1,//是否有效随访
//                    ];
//
//                    //追加随访时间到患者信息
//                    $pFollowTime = [
//                        'history_id' => (string)$answerInfo["history_id"],
//                        'pushtime' => date('Y-m-d'),
//                    ];
//                    //查询当前患者pid
//                    (new TaskService())->appendFollowNode($followInfo['pid'], $pResult, $pFollowTime);
//
//                }
//                if (isset($answerInfo['follow_id']) && $answerInfo["follow_id"] !== 0 || $answerInfo["is_auto"] === 1) {
//
//                    //回写follow_history表状态
//                    (new FollowHistory())->saveData($answerInfo["history_id"],
//                        [
//                            "status" => 2,
//                            "finish_date" => date("Y-m-d"),
//                            "result" => 29,
//                            "resultName" => "生存",
//                            "resultIsEffective" => 1,
//                            "resultCategory" => 0
//                        ]
//                    );
//                }
//                //判断问卷id是否绑定过节点问卷
//                if (isset($answerInfo["patientDeptId"]) && !empty($answerInfo["patientDeptId"])) {
//                    $nodeInfo = (new \app\common\model\Node())->where([["project_id", "=", $data["projectId"]]])->where(function ($query) use ($answerInfo) {
//                        $query->whereOr([["apply_dept.dept_id", "=", (int)$answerInfo["patientDeptId"]], ["is_whole_hospital", "=", 1]]);
//                    })->order("is_whole_hospital", "asc")->limit(1)->find();
//                    if (!empty($nodeInfo)) {
//                        # 执行回复量+1
//                        ZhyxMongo::getInstance()->setCollection('node')->updateOne(["_id" => new ObjectId($nodeInfo["id"])], ['$inc' => ['answer_count' => 1]]);
//                    }
//                }
//                $session->commitTransaction();
//
//                # 判断答案中是否包含异常题目
//                if (isset($data["flag"]) && $data["flag"] === true) {
//
//                    $edId = $data["ed_id"] ?? [];
//
//                    $expMessage = [
//                        'tubeName' => 'PushProjectExpMessage',
//                        'ed_id' => $edId,
//                        'answer_id' => $data["answer_id"] ?: (string)$answerInfo['_id']
//                    ];
//
//                    ZhyxBeanstalkd::getInstance()->beansTalk->useTube("pushProjectExpMessage")->put(json_encode($expMessage, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE));
//                }
//
//                #判断是否包含随访路径id，如果包含执行更新状态
//                if (isset($data["history_id"]) && !empty($data["history_id"])) {
//                    (new DiseasePatientTaskDetail())->modifyStatus($data["history_id"]);
//                }
//            }
//
//        } catch (\Exception $exception) {
//
//            if ($session->getTransactionState() !== "none") {
//                $session->abortTransaction();
//            }
//            throw  new FailedException($exception->getMessage());
//        }
//        return ["id" => (string)$answerInfo["history_id"], "status" => 2];
//
//    }

    public function getList(): \think\Paginator
    {
        $result = $this->model->getLists();
        if (count($result->items()) > 0) {
            $result->append(["startTimeText", "endTimeText", "statusText", "putChanelText"]);
        }
        return $result;
    }

    public function initQuestion(array $data): array
    {

        try {
            //根据projectId获取问卷信息
            $questionInfo = (new Project())->getProjectInfo($data["projectId"]);
            if (empty($questionInfo)) {
                throw new FailedException("问卷不存在");
            }
            $answerArr = [];
            //循环写入到问卷中
            foreach ($data["patientList"] as $k => $v) {
                $v["putChanel"] = $data["putChanel"];
                $v["creator_id"] = $data["creator_id"] ?? 0;
                $v["creator_dept_id"] = $data["creator_dept_id"] ?? 0;
                $v["creator_dept_name"] = $data["creator_dept_name"] ?? "";
                $v["answer_no"] = Str::getAnswerNo();
                $v["status"] = 0;
                $v["questions"] = $questionInfo->toArray();
                $v["projectId"] = $data["projectId"];
                $v["answer"] = [];
                $v["deleted_at"] = 0;
                $v["created_at"] = time();
                $v["history_id"] = isset($v["history_id"]) ? new ObjectId($v["history_id"]) : '';
                $v["task_id"] = isset($v["task_id"]) && !empty($v["task_id"]) ? new ObjectId($v['task_id']) : '';
                $v["is_auto"] = $v["is_auto"] ?? 0;
                $answerId = $this->model->insert($v, true);

                $answerArr[] = $answerId;

                if ($answerId && !empty($v["history_id"])) {

                    (new FollowHistory())->saveData($v["history_id"], ["answer_id" => $answerId]);
                }
            }

            //判断问卷类型是否是节点问卷
            if ($questionInfo["survey_type"] === 2 && isset($questionInfo["point"])) {
                $this->calculatingData($answerArr[0], $questionInfo);
            }

            return ["answer_ids" => count($answerArr) > 1 ? $answerArr : $answerArr[0]];
        } catch (Exception $exception) {
            throw new FailedException($exception->getMessage());
        }
    }

    public function calculatingData(string $answerId, $questionInfo)
    {
        try {

            $answerInfo = $this->model->where("id", "=", $answerId)->find();
            $condition = [];
            $condition[] = ["node_id", "=", $questionInfo["point"]];
            $condition[] = ["project_id", "=", $questionInfo["projectId"]];
            $condition[] = ["deleted_at", "=", 0];
            $nodeInfo = (new \app\common\model\Node())->where($condition)->where(function ($query) use ($answerInfo) {
                $query->whereOr([["apply_dept.dept_id", "=", (int)$answerInfo["patientDeptId"]], ["is_whole_hospital", "=", 1]]);
            })->order("is_whole_hospital", "asc")->limit(1)->find();

            if (!empty($nodeInfo)) {
                //$nodeInfo->inc("send_count", 1)->save();
                ZhyxMongo::getInstance()->setCollection('node')->updateOne(["_id" => new ObjectId($nodeInfo["id"])], ['$inc' => ['send_count' => 1]]);

            }
            return true;
        } catch (\Exception $exception) {
            Log::error($exception->getMessage());
        }

    }

    public function getSummary(string $projectId): array
    {
        $result = $this->model->getCountByStatus($projectId);
        return [
            "total" => array_sum($result),
            "processing" => $result[1] ?? 0,
            "completed" => $result[2] ?? 0,
            "undone" => $result[0] ?? 0
        ];
    }

    public function getAnswerById(string $id)
    {
        return ZhyxMongo::getInstance()->setCollection("answer")->findOne(["_id" => new ObjectId($id)]);

    }

    public function getAnswerByFollowId(string $followId)
    {
        return ZhyxMongo::getInstance()->setCollection("answer")->findOne(["follow_id" => $followId]);

    }

    public function getChronicDisease(string $hisId, int $type)
    {
        $condition[] = ["patient_id", "=", $hisId];
        $condition[] = ["questions.survey_type", "=", 3];
        $condition[] = ["questions.estimateType", "=", $type];
        return $this->model->where($condition)->field(["id", "created_at", "creator_name", "name" => '$questions.name', "answer", "history_id", "projectId", "status"])->order("_id", "desc")->select();
    }


}
